package com.sc.nft.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sc.nft.admin.request.IdRequest;
import com.sc.nft.admin.vo.EquityProfitRuleVO;
import com.sc.nft.admin.vo.EquitySharePanelVO;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.dao.DigitalCollectionDao;
import com.sc.nft.dao.EquityProfitRuleDao;
import com.sc.nft.dao.EquitySharePanelDao;
import com.sc.nft.dao.SecondEquityPropsConfigDao;
import com.sc.nft.dto.*;
import com.sc.nft.entity.DigitalCollection;
import com.sc.nft.entity.EquityProfitRule;
import com.sc.nft.entity.EquitySharePanel;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/equity/share")
@Api(tags = "道具分红控制器")
public class EquityShareAdminController {

    private final EquitySharePanelDao equitySharePanelDao;
    private final EquityProfitRuleDao equityProfitRuleDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final SecondEquityPropsConfigDao secondEquityPropsConfigDao;

    @PostMapping(value = "/simpleList", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "分红模板简单列表", notes = "分红模板简单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<List<EquitySharePanelVO>> simpleList() {
        return Result.successColl(equitySharePanelDao.findByStatus(true), EquitySharePanelVO.class);
    }

    @PostMapping(value = "/addPanel", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "添加分红模板", notes = "添加分红模板", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result addPanel(@Validated @RequestBody AddEquitySharePanelDTO dto) {
        dto.checkRatio();
        if (ObjectUtil.isNotNull(equitySharePanelDao.findByName(dto.getPanelName()))) {
            return Result.fail("模板名称已存在");
        }
        EquitySharePanel sharePanel = new EquitySharePanel();
        sharePanel.setPanelName(dto.getPanelName());
        sharePanel.setShareRatio(dto.getShareRatio());
        sharePanel.setMetaMapRatio(dto.getMetaMapProvinceRatio());
        sharePanel.setMetaMapCityRatio(dto.getMetaMapCityRatio());
        sharePanel.setMetaMapRegionRatio(dto.getMetaMapRegionRatio());
        sharePanel.setSharePoolId(1L);
        sharePanel.setStatus(false);
        sharePanel.insert();
        return Result.success();
    }

    @PostMapping(value = "/addRule", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "添加收益规则", notes = "添加收益规则", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result addRule(@Validated @RequestBody AddEquityShareRuleDTO dto) {
        if (ObjectUtil.isNotNull(equityProfitRuleDao.findByName(dto.getProfitName()))) {
            return Result.fail("收益名称已存在");
        }
        Assert.notNull(digitalCollectionDao.getById(dto.getCollectionId()), () -> new GlobalRunTimeException(ErrorCode.COLLECTION_NOT_FOUND));

        BigDecimal sumRatio = BigDecimal.ZERO;
        List<EquityProfitRule> list = equityProfitRuleDao.list();
        if (CollUtil.isNotEmpty(list)) {
            sumRatio = list.stream().map(EquityProfitRule::getShareRatio).reduce(BigDecimal::add).get();
        }
        if (NumberUtil.isGreater(sumRatio.add(dto.getShareRatio()), BigDecimal.ONE)) {
            return Result.fail("累计分红比例大于1");
        }

        EquityProfitRule profitRule = new EquityProfitRule();
        profitRule.setProfitName(dto.getProfitName());
        profitRule.setCollectionId(dto.getCollectionId());
        profitRule.setStatus(false);
        profitRule.setShareRatio(dto.getShareRatio());
        profitRule.setSharePoolId(1L);
        profitRule.insert();
        return Result.success();
    }


    @PostMapping(value = "/editPanel", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "编辑分红模板", notes = "编辑分红模板", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editPanel(@Validated @RequestBody EditEquitySharePanelDTO dto) {
        dto.checkRatio();
        EquitySharePanel equitySharePanel = equitySharePanelDao.getById(dto.getId());
        if (ObjectUtil.isNull(equitySharePanel)) {
            return Result.fail("模板不存在");
        }
        EquitySharePanel byName = equitySharePanelDao.findByName(dto.getPanelName());
        if (ObjectUtil.isNotNull(byName) && byName.getId().longValue() != equitySharePanel.getId().longValue()) {
            return Result.fail("模板名称已存在");
        }
        equitySharePanel.setPanelName(dto.getPanelName());
        equitySharePanel.setShareRatio(dto.getShareRatio());
        equitySharePanel.setMetaMapRatio(dto.getMetaMapProvinceRatio());
        equitySharePanel.setMetaMapCityRatio(dto.getMetaMapCityRatio());
        equitySharePanel.setMetaMapRegionRatio(dto.getMetaMapRegionRatio());
        equitySharePanel.updateById();
        return Result.success();
    }


    @PostMapping(value = "/editRule", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "编辑收益规则", notes = "编辑收益规则", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editRule(@Validated @RequestBody EditEquityShareRuleDTO dto) {
        EquityProfitRule equityProfitRule = equityProfitRuleDao.getById(dto.getId());
        if (ObjectUtil.isNull(equityProfitRule)) {
            return Result.fail("收益规则不存在");
        }
        EquityProfitRule byName = equityProfitRuleDao.findByName(dto.getProfitName());
        if (ObjectUtil.isNotNull(byName) && byName.getId().longValue() != equityProfitRule.getId().longValue()) {
            return Result.fail("收益规则名称已存在");
        }
        Assert.notNull(digitalCollectionDao.getById(dto.getCollectionId()), () -> new GlobalRunTimeException(ErrorCode.COLLECTION_NOT_FOUND));

        BigDecimal sumRatio = BigDecimal.ZERO;
        List<EquityProfitRule> list = equityProfitRuleDao.list();
        if (CollUtil.isNotEmpty(list)) {
            sumRatio = list.stream().filter(x -> x.getId().longValue() != dto.getId().longValue()).map(EquityProfitRule::getShareRatio).reduce(BigDecimal::add).get();
        }
        if (NumberUtil.isGreater(sumRatio.add(dto.getShareRatio()), BigDecimal.ONE)) {
            return Result.fail("累计分红比例大于1");
        }

        equityProfitRule.setCollectionId(dto.getCollectionId());
        equityProfitRule.setProfitName(dto.getProfitName());
        equityProfitRule.setShareRatio(dto.getShareRatio());
        equityProfitRule.updateById();
        return Result.success();
    }


    @PostMapping(value = "/removeRule", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "删除收益规则", notes = "删除收益规则", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result removeRule(@Validated @RequestBody IdRequest dto) {
        EquityProfitRule equityProfitRule = equityProfitRuleDao.getById(dto.getId());
        if (ObjectUtil.isNull(equityProfitRule)) {
            return Result.fail("收益规则不存在");
        }
        equityProfitRule.deleteById();
        return Result.success();
    }

    @PostMapping(value = "/panelPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "模板列表", notes = "模板列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<EquitySharePanelVO> panelPage(@Validated @RequestBody EquityPanelPageRequest request) {
        Page<EquitySharePanel> pageByName = equitySharePanelDao.findPageByName(request.toMp(), request.getPanelName(), request.getStatus());
        IPage<EquitySharePanelVO> convert = pageByName.convert(x -> {
            EquitySharePanelVO equitySharePanelVO = new EquitySharePanelVO();
            equitySharePanelVO.setId(x.getId());
            equitySharePanelVO.setPanelName(x.getPanelName());
            equitySharePanelVO.setShareRatio(x.getShareRatio());
            equitySharePanelVO.setMetaMapProvinceRatio(x.getMetaMapRatio());
            equitySharePanelVO.setMetaMapCityRatio(x.getMetaMapCityRatio());
            equitySharePanelVO.setMetaMapRegionRatio(x.getMetaMapRegionRatio());
            equitySharePanelVO.setStatus(x.getStatus());
            equitySharePanelVO.setCreateTime(x.getCreateTime());
            return equitySharePanelVO;
        });
        return PageResult.success(convert);
    }

    @PostMapping(value = "/profitPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "收益规则列表", notes = "收益规则列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<EquityProfitRuleVO> profitPage(@Validated @RequestBody EquityRulePageRequest request) {
        Page<EquityProfitRule> pageByName = equityProfitRuleDao.findPageByName(request.toMp(), request.getProfitName(), request.getStatus());
        Page<EquityProfitRuleVO> resultPage = new Page<>(pageByName.getCurrent(), pageByName.getSize(), pageByName.getTotal());
        List<EquityProfitRuleVO> result = Lists.newArrayList();
        for (EquityProfitRule record : pageByName.getRecords()) {
            EquityProfitRuleVO equityProfitRuleVO = BeanUtil.toBean(record, EquityProfitRuleVO.class);
            DigitalCollection collection = digitalCollectionDao.getById(record.getCollectionId());
            equityProfitRuleVO.setCollectionName(collection.getFirstTitle());
            result.add(equityProfitRuleVO);
        }
        resultPage.setRecords(result);
        return PageResult.success(resultPage);
    }


    @PostMapping(value = "/onShiftPanel", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "启用模板", notes = "启用模板", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result onShiftPanel(@Validated @RequestBody IdRequest request) {
        EquitySharePanel equitySharePanel = equitySharePanelDao.getById(request.getId());
        if (ObjectUtil.isNull(equitySharePanel)) {
            return Result.fail("模板不存在");
        }
        equitySharePanel.setStatus(true);
        equitySharePanel.updateById();
        return Result.success();
    }

    @PostMapping(value = "/offShiftPanel", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "禁用模板", notes = "禁用模板", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result offShiftPanel(@Validated @RequestBody IdRequest request) {
        EquitySharePanel equitySharePanel = equitySharePanelDao.getById(request.getId());
        if (ObjectUtil.isNull(equitySharePanel)) {
            return Result.fail("模板不存在");
        }
        equitySharePanel.setStatus(false);
        equitySharePanel.updateById();
        return Result.success();
    }


    @PostMapping(value = "/onShiftRule", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "启用规则", notes = "启用规则", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result onShiftRule(@Validated @RequestBody IdRequest request) {
        EquityProfitRule profitRule = equityProfitRuleDao.getById(request.getId());
        if (ObjectUtil.isNull(profitRule)) {
            return Result.fail("规则不存在");
        }
        profitRule.setStatus(true);
        profitRule.updateById();
        return Result.success();
    }

    @PostMapping(value = "/offShiftRule", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "禁用规则", notes = "禁用规则", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result offShiftRule(@Validated @RequestBody IdRequest request) {
        EquityProfitRule profitRule = equityProfitRuleDao.getById(request.getId());
        if (ObjectUtil.isNull(profitRule)) {
            return Result.fail("规则不存在");
        }
        profitRule.setStatus(false);
        profitRule.updateById();
        return Result.success();
    }

    @PostMapping(value = "/pageRelationProps", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "模板关联道具", notes = "模板关联道具", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<SimplePropsDTO>> pageRelationProps(@Validated @RequestBody IdRequest request) {
        return Result.success(secondEquityPropsConfigDao.getPropsByPanelId(request.getId()));
    }

}
